{
  "name": "Case 69 - Franchise Store Success Analysis",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -816,
        -64
      ],
      "id": "c8bdd802-42df-447a-b9f0-f1fe714fba25",
      "name": "Weekly Schedule - Monday 9 AM"
    },
    {
      "parameters": {
        "actorId": {
          "__rl": true,
          "value": "Xb8osYTtOjlsgI6k9",
          "mode": "id",
          "cachedResultName": "Google Maps Scraper"
        },
        "customBody": "{\n  \"language\": \"en\",\n  \"maxReviews\": 50,\n  \"personalData\": true,\n  \n  \"startUrls\": [\n    {\n    \"url\": \"https://www.google.com/maps/search/Planet+Fitness+215+W+35th+Street+New+York\"\n    },\n    {\n    \"url\": \"https://www.google.com/maps/search/Planet+Fitness+25+Broadway+New+York\"\n    },\n    {\n    \"url\": \"https://www.google.com/maps/search/Planet+Fitness+22+E+14th+Street+New+York\"\n    }\n  ],\n  \"reviewsSort\": \"newest\",\n  \"reviewsOrigin\": \"all\"\n}"
      },
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        -624,
        -64
      ],
      "id": "aac595e3-5cb0-409a-81fe-ec30c70f7ac7",
      "name": "Scrape 3 Franchise Locations",
      "credentials": {
        "apifyApi": {
          "id": "w5S6YBbbyUddEfQA",
          "name": "Apify account"
        }
      }
    },
    {
      "parameters": {
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}",
        "limit": 150
      },
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        -432,
        -64
      ],
      "id": "2c0d3f60-13c6-4c3d-9426-eefec3408d60",
      "name": "Get Dataset Items",
      "credentials": {
        "apifyApi": {
          "id": "w5S6YBbbyUddEfQA",
          "name": "Apify account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "filter-4star",
              "leftValue": "={{ $json.stars }}",
              "rightValue": 4,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            },
            {
              "id": "filter-5star",
              "leftValue": "={{ $json.stars }}",
              "rightValue": 5,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2,
      "position": [
        -240,
        -64
      ],
      "id": "ab0b2f78-0c72-4e02-9a3e-1aa452c64da1",
      "name": "Filter 4-5 Star Reviews"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o",
          "mode": "list",
          "cachedResultName": "GPT-4o"
        },
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are a Franchise Performance Analyst. Read the positive review carefully and identify success factors.\n\nReturn ONLY this JSON format:\n{\n  \"success_category\": \"Location Advantages|Traffic Patterns|Customer Demographics|Service Excellence|Menu Popularity|Staff Quality|Other\",\n  \"insight_value\": \"high|medium|low\",\n  \"replicability\": \"Easy to Replicate|Requires Investment|Location Specific|Staff Dependent\",\n  \"key_success_factor\": \"specific thing that's working well\",\n  \"key_quote\": \"most important sentence from review\"\n}\n\nHOW TO CATEGORIZE:\n\nLocation Advantages = Proximity benefits, visibility, accessibility\nKeywords: convenient location, near office, easy to find, great spot\nExample: \"Perfect location right by my office\" → Location Advantages\n\nTraffic Patterns = Busy times, customer flow, volume indicators\nKeywords: always busy, lunch rush, packed, line out the door\nExample: \"Always packed during lunch\" → Traffic Patterns\n\nCustomer Demographics = Who shops here, family-friendly, professional crowd\nKeywords: families love it, business lunch, college students\nExample: \"Great for families with kids\" → Customer Demographics\n\nService Excellence = What makes service outstanding\nKeywords: fast service, friendly staff, personalized, efficient\nExample: \"They remember my name\" → Service Excellence\n\nMenu Popularity = Specific items praised\nKeywords: love the sandwich, best fries, breakfast amazing\nExample: \"Their waffle fries are the best\" → Menu Popularity\n\nStaff Quality = Team excellence, manager mentions\nKeywords: amazing staff, manager great, well-trained\nExample: \"Staff is incredibly friendly\" → Staff Quality\n\nOther = Everything else\n\nINSIGHT VALUE:\n- high: Competitive advantage, frequently mentioned\n- medium: Notable positive\n- low: Nice to have\n\nREPLICABILITY:\n- Easy to Replicate: Training, processes\n- Requires Investment: Technology, equipment\n- Location Specific: Unique geography\n- Staff Dependent: Specific individuals\n\nReturn ONLY the JSON. No explanation."
            },
            {
              "content": "=Analyze this franchise review:\n\nLocation: {{ $json.title }}\nReviewer: {{ $json.name }}\nRating: {{ $json.stars }} stars\nDate: {{ $json.publishedAtDate }}\nReview: {{ $json.text }}\n\nReturn only JSON."
            }
          ]
        },
        "builtInTools": {},
        "options": {
          "maxTokens": 500
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.1,
      "position": [
        -48,
        -64
      ],
      "id": "58cc6286-2302-4610-b97a-cf95af57952e",
      "name": "AI: Analyze Success Factors",
      "credentials": {
        "openAiApi": {
          "id": "ICwxUBbatsF2sDvy",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// ENHANCED AI RESPONSE PARSER WITH DEBUGGING\nconst items = [];\nconst input = $input.all();\n\ninput.forEach((item, index) => {\n  try {\n    // Get the raw AI response\n    const aiText = item.json.output[0].content[0].text;\n    \n    // Multiple cleaning strategies\n    let cleaned = aiText\n      .replace(/```json\\n?/gi, '')  // Remove ```json\n      .replace(/```\\n?/g, '')         // Remove ```\n      .replace(/^[^{]*/, '')          // Remove everything before first {\n      .replace(/[^}]*$/, '')          // Remove everything after last }\n      .trim();\n    \n    // Try to parse\n    const parsed = JSON.parse(cleaned);\n    \n    // Validate required fields exist\n    if (!parsed.success_category || !parsed.insight_value || !parsed.replicability) {\n      throw new Error('Missing required fields');\n    }\n    \n    items.push({ json: parsed });\n    \n  } catch (error) {\n    // Log the actual error for debugging\n    console.error(`Parse error for item ${index}:`, error.message);\n    console.error('Raw AI text:', item.json.output[0].content[0].text);\n    \n    // Return error placeholder with actual error message\n    items.push({\n      json: {\n        success_category: 'Other',\n        insight_value: 'low',\n        replicability: 'Easy to Replicate',\n        key_success_factor: `Parse error: ${error.message}`,\n        key_quote: ''\n      }\n    });\n  }\n});\n\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        -64
      ],
      "id": "b8354b13-fed5-4d36-b3f0-49d53b58d07a",
      "name": "Parse AI Response"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cat",
              "name": "success_category",
              "value": "={{ $json.success_category }}",
              "type": "string"
            },
            {
              "id": "value",
              "name": "insight_value",
              "value": "={{ $json.insight_value }}",
              "type": "string"
            },
            {
              "id": "repl",
              "name": "replicability",
              "value": "={{ $json.replicability }}",
              "type": "string"
            },
            {
              "id": "factor",
              "name": "key_success_factor",
              "value": "={{ $json.key_success_factor && $json.key_success_factor.includes('Parse error') ? 'Not sufficient data available' : $json.key_success_factor }}",
              "type": "string"
            },
            {
              "id": "quote",
              "name": "key_quote",
              "value": "={{ $json.key_quote }}",
              "type": "string"
            },
            {
              "id": "date",
              "name": "review_date",
              "value": "={{ $('Filter 4-5 Star Reviews').item.json.publishedAtDate }}",
              "type": "string"
            },
            {
              "id": "store",
              "name": "store_location",
              "value": "={{ $('Filter 4-5 Star Reviews').item.json.address }}",
              "type": "string"
            },
            {
              "id": "reviewer",
              "name": "reviewer_name",
              "value": "={{ $('Filter 4-5 Star Reviews').item.json.name }}",
              "type": "string"
            },
            {
              "id": "rating",
              "name": "star_rating",
              "value": "={{ $('Filter 4-5 Star Reviews').item.json.stars }}",
              "type": "number"
            },
            {
              "id": "text",
              "name": "review_text",
              "value": "={{ $('Filter 4-5 Star Reviews').item.json.textTranslated || $('Filter 4-5 Star Reviews').item.json.text }}",
              "type": "string"
            },
            {
              "id": "url",
              "name": "review_url",
              "value": "={{ $('Filter 4-5 Star Reviews').item.json.reviewUrl }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        400,
        -64
      ],
      "id": "19d70f63-075e-4746-9ddb-75cc4d482a61",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "18IaKcYKUK99lwHkaU_-rbFMSreZgOj6tEisk2ruq4dU",
          "mode": "list",
          "cachedResultName": "Case 69 - Franchise Store Success Analysis Log",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18IaKcYKUK99lwHkaU_-rbFMSreZgOj6tEisk2ruq4dU/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Sheet1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18IaKcYKUK99lwHkaU_-rbFMSreZgOj6tEisk2ruq4dU/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Review_Date": "={{ $json.review_date }}",
            "Store_Location": "={{ $json.store_location }}",
            "Reviewer_Name": "={{ $json.reviewer_name }}",
            "Star_Rating": "={{ $json.star_rating }}",
            "Review_Text": "={{ $json.review_text }}",
            "Success_Category": "={{ $json.success_category }}",
            "Insight_Value": "={{ $json.insight_value }}",
            "Replicability": "={{ $json.replicability }}",
            "Key_Success_Factor": "={{ $json.key_success_factor }}",
            "Key_Quote": "={{ $json.key_quote }}",
            "Review_URL": "={{ $json.review_url }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "Review_Date",
              "displayName": "Review_Date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Store_Location",
              "displayName": "Store_Location",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Reviewer_Name",
              "displayName": "Reviewer_Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Star_Rating",
              "displayName": "Star_Rating",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Review_Text",
              "displayName": "Review_Text",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Success_Category",
              "displayName": "Success_Category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Insight_Value",
              "displayName": "Insight_Value",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Replicability",
              "displayName": "Replicability",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Key_Success_Factor",
              "displayName": "Key_Success_Factor",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Key_Quote",
              "displayName": "Key_Quote",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Review_URL",
              "displayName": "Review_URL",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        560,
        -64
      ],
      "id": "21874b68-d422-4fdb-9aa7-30eb4faf0b3d",
      "name": "Log to Google Sheet",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "LOs2dbk9lby0NfDM",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const items = $('Edit Fields').all();\n\nif (items.length === 0) {\n  return [{ json: { total_reviews: 0, locations: [], category_breakdown: {}, insight_breakdown: {}, replicability_breakdown: {}, top_insights: [], location_performance: {} } }];\n}\n\nconst categoryCount = {};\nconst insightCount = {};\nconst replicabilityCount = {};\nconst allInsights = [];\nconst locationCount = {};\nconst locationNames = new Set();\n\nitems.forEach(item => {\n  const data = item.json;\n  const store = data.store_location || 'Unknown';\n  \n  locationNames.add(store);\n  locationCount[store] = (locationCount[store] || 0) + 1;\n  \n  const category = data.success_category || 'Other';\n  categoryCount[category] = (categoryCount[category] || 0) + 1;\n  \n  const insight = data.insight_value || 'low';\n  insightCount[insight] = (insightCount[insight] || 0) + 1;\n  \n  const repl = data.replicability || 'Easy to Replicate';\n  replicabilityCount[repl] = (replicabilityCount[repl] || 0) + 1;\n  \n  allInsights.push({\n    factor: data.key_success_factor || '',\n    quote: data.key_quote || '',\n    reviewer: data.reviewer_name || 'Anonymous',\n    date: data.review_date || '',\n    rating: data.star_rating || 0,\n    url: data.review_url || '',\n    insight_value: data.insight_value || 'low',\n    category: data.success_category || 'Other',\n    replicability: data.replicability || 'Easy to Replicate',\n    store: store\n  });\n});\n\nconst insightOrder = { high: 3, medium: 2, low: 1 };\nallInsights.sort((a, b) => (insightOrder[b.insight_value] || 0) - (insightOrder[a.insight_value] || 0));\nconst topInsights = allInsights.slice(0, 10);\n\nreturn [{ \n  json: { \n    total_reviews: items.length, \n    locations: Array.from(locationNames),\n    location_performance: locationCount,\n    category_breakdown: categoryCount, \n    insight_breakdown: insightCount, \n    replicability_breakdown: replicabilityCount, \n    top_insights: topInsights\n  } \n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        -64
      ],
      "id": "160f357e-4557-4f56-9bab-f17df79bf96f",
      "name": "Aggregate Cross-Location Insights"
    },
    {
      "parameters": {
        "sendTo": "franchisehead@company.com",
        "subject": "Weekly 3-Store Success Pattern Report",
        "emailType": "text",
        "message": "=WEEKLY 3-STORE SUCCESS ANALYSIS\n================================\n\nTotal Reviews Analyzed: {{ $json.total_reviews }}\nStores: {{ $json.locations.length }}\n\nPERFORMANCE BY LOCATION:\n{{ Object.keys($json.location_performance).map(loc => loc + ': ' + $json.location_performance[loc] + ' reviews').join('\\n') }}\n\nSUCCESS CATEGORIES:\n{{ Object.keys($json.category_breakdown).map(cat => cat + ': ' + $json.category_breakdown[cat]).join('\\n') }}\n\nREPLICABILITY:\n{{ Object.keys($json.replicability_breakdown).map(repl => repl + ': ' + $json.replicability_breakdown[repl]).join('\\n') }}\n\nTOP 10 INSIGHTS:\n{{ $json.top_insights.map((insight, i) => (i+1) + '. ' + insight.category + ' (' + insight.insight_value + ')\\n   Store: ' + insight.store + '\\n   Factor: ' + insight.factor + '\\n   Quote: \"' + insight.quote + '\"\\n   Replicability: ' + insight.replicability).join('\\n\\n') }}\n\nRECOMMENDATIONS:\n- Implement Easy to Replicate practices immediately\n- Document success factors appearing at multiple locations\n- Use Staff Quality insights for training programs\n- Evaluate Requires Investment items for ROI\n- Apply Location Advantages to site selection criteria\n\nGenerated: {{ new Date().toLocaleDateString() }}",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        912,
        -64
      ],
      "id": "947e91ab-c64d-41d6-9215-2c644bd28e82",
      "name": "Send Weekly Success Report",
      "webhookId": "d56df740-8f6e-4e06-9478-a8ead77000a4",
      "credentials": {
        "gmailOAuth2": {
          "id": "cyqCGWcggZNMcSOv",
          "name": "Gmail account"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "Weekly Schedule - Monday 9 AM": {
      "main": [
        [
          {
            "node": "Scrape 3 Franchise Locations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape 3 Franchise Locations": {
      "main": [
        [
          {
            "node": "Get Dataset Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Dataset Items": {
      "main": [
        [
          {
            "node": "Filter 4-5 Star Reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter 4-5 Star Reviews": {
      "main": [
        [
          {
            "node": "AI: Analyze Success Factors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI: Analyze Success Factors": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Log to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheet": {
      "main": [
        [
          {
            "node": "Aggregate Cross-Location Insights",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Cross-Location Insights": {
      "main": [
        [
          {
            "node": "Send Weekly Success Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9a45f88a-3d5e-44a6-9e80-7fb3e5e49a63",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "3a43da28588548e21903e71cf1dc3ddd65c24bf0c62e7e4b77542ffe87ad79c6"
  },
  "id": "5LDcvNXEdTOiG1MB",
  "tags": []
}